﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Defect_Tracking_System.Models
{
    public class EmailNotification
    {
        private static EmailNotification instance;

        private List<EmailNotifyArg> Args;
        private List<ICommand> Commands;
        private String Id;
        private String Status;
        private String Priority;
        private String AsignerUserName;
        private bool IsClosed;
        private String Editor;
        private AccountManagement AM = AccountManagement.GetInstance();
        private DefectManagement DM = DefectManagement.GetInstance();
      

        public static EmailNotification GetIntance()
        {
            if(instance==null)
            {
                instance = new EmailNotification();
            }

            return instance;
        }

        private EmailNotification()
        {
            Args = new List<EmailNotifyArg>();
            Commands = new List<ICommand>();
        }

        public void BeginChangeDefect(String DefectId, String Editor)
        {
            AsignerUserName = null;

            Defect defect = DM.GetDefect(DefectId);
            if (defect != null)
            {
                Id = defect.DefectId.ToString();
                Status = defect.Status;
                Priority = defect.Priority;
                if (defect.AccountAssignedMember != null)
                {
                    AsignerUserName = defect.AccountAssignedMember.UserName;
                }
                IsClosed = defect.IsClosed;
            }
            this.Editor = Editor;
        }

        public void EndChangeDefect()
        {
            if (Id != null)
            {
                Defect defect = DM.GetDefect(Id);
                if (Status != defect.Status)
                {
                    StatusChangedEmailNotifyArg Arg = new StatusChangedEmailNotifyArg();
                    Arg.DefectId = Id;
                    Arg.EditorUserName = Editor;
                    Arg.NewStatus = defect.Status;
                    Arg.OldStatus = Status;
                    Args.Add(Arg);
                }
                if (Priority != defect.Priority)
                {
                    PriorityChangedEmailNotifyArg Arg = new PriorityChangedEmailNotifyArg();
                    Arg.DefectId = Id;
                    Arg.EditorUserName = Editor;
                    Arg.NewPriority = defect.Priority;
                    Arg.OldPriority = Priority;
                    Args.Add(Arg);
                }
                if (defect.AssignedMember!=null || AsignerUserName !=null)
                {
                    if (defect.AssignedMember == null && AsignerUserName != null)
                    {
                        AssignerChangedEmailNotifyArg Arg = new AssignerChangedEmailNotifyArg();
                        Arg.DefectId = Id;
                        Arg.EditorUserName = Editor;
                        Arg.NewAsignerUserName = null;
                        Arg.OldAsignerUserName = AsignerUserName;
                        Args.Add(Arg);
                    }
                    else if (AsignerUserName != defect.AccountAssignedMember.UserName)
                    {
                        AssignerChangedEmailNotifyArg Arg = new AssignerChangedEmailNotifyArg();
                        Arg.DefectId = Id;
                        Arg.EditorUserName = Editor;
                        Arg.NewAsignerUserName = defect.AccountAssignedMember.UserName;
                        Arg.OldAsignerUserName = AsignerUserName;
                        Args.Add(Arg);
                    }
                }
                if (IsClosed != defect.IsClosed)
                {
                    DefectClosedReOpenedEmailNotifyArg Arg = new DefectClosedReOpenedEmailNotifyArg();
                    Arg.DefectId = Id;
                    Arg.EditorUserName = Editor;
                    Args.Add(Arg);
                }
                Notify();
                EmailSender.GetInstance().Send();
            }
        }

        public void NotifyComment(String CommentId)
        {
            CommentOnDefectEmailNotifyArg Arg = new CommentOnDefectEmailNotifyArg();
            Arg.CommentId = CommentId;
            Args.Add(Arg);
            Notify();
            EmailSender.GetInstance().Send();
        }

        public void NotifyDisableEnableAccount(String UserName)
        {
            DisableEnableAccountEmailNotifyArg Arg = new DisableEnableAccountEmailNotifyArg();
            Arg.UserName = UserName;
            Args.Add(Arg);
            Notify();
            EmailSender.GetInstance().Send();
        }

        public void NotifyChangeProjectMember(String ProjectId, String UserName)
        {
            ChangedProjectMembersEmailNotifyArg Arg = new ChangedProjectMembersEmailNotifyArg();
            Arg.ProjectId = ProjectId;
            Arg.UserName = UserName;
            Args.Add(Arg);
            Notify();
            EmailSender.GetInstance().Send();
        }

        public void NotifyDefectCreated(String DefectId)
        {
            DefectCreatedNotifyArg Arg = new DefectCreatedNotifyArg();
            Arg.DefectId = DefectId;
            Args.Add(Arg);
            Notify();
            EmailSender.GetInstance().Send();
        }

        public void NotifyResetPassword(String UserName, String NewPassword)
        {
            PasswordResetedEmailNotifyArg Arg = new PasswordResetedEmailNotifyArg();
            Arg.UserName = UserName;
            Arg.NewPassword = NewPassword;
            Args.Add(Arg);
            Notify();
            EmailSender.GetInstance().Send();
        }

        public void Notify()
        {
            foreach (EmailNotifyArg Arg in Args)
            {
                switch (Arg.Type)
                {
                    case EmailNotificationType.ChangedProjectMembers:
                        new ChangedProjectMembersNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.CommentOnDefect:
                        new CommentOnDefectNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.DefectAssignerChanged:
                        new DefectAssignerChangedNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.DefectClosedReopened:
                        new DefectClosedReopenedNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.DefectCreated:
                        new DefectCreatedNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.DefectPriorityChanged:
                        new DefectPriorityChangedNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.DefectStatusChanged:
                        new DefectStatusChangedNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.DisableEnableAccount:
                        new DisableEnableAccountNotifier().Execute(Arg);
                        break;
                    case EmailNotificationType.ResetPassword:
                        new ResetPasswordNotifier().Execute(Arg);
                        break;
                }
            }
            Args = new List<EmailNotifyArg>();
        }


    }

    #region Email Notify Arguments
    public interface EmailNotifyArg
    {
        EmailNotificationType Type { get; }
    }

    public class StatusChangedEmailNotifyArg : EmailNotifyArg
    {
        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.DefectStatusChanged; }
        }

        #endregion

        public String DefectId { get; set; }
        public String OldStatus { get; set; }
        public String NewStatus { get; set; }
        public String EditorUserName { get; set; }
    }

    public class DefectCreatedNotifyArg : EmailNotifyArg
    {
        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.DefectCreated; }
        }

        #endregion

        public String DefectId { get; set; }
    }

    public class PriorityChangedEmailNotifyArg : EmailNotifyArg
    {
        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.DefectPriorityChanged; }
        }

        #endregion

        public String DefectId { get; set; }
        public String OldPriority { get; set; }
        public String NewPriority { get; set; }
        public String EditorUserName { get; set; }
    }

    public class AssignerChangedEmailNotifyArg : EmailNotifyArg
    {
        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.DefectAssignerChanged; }
        }

        #endregion

        public String DefectId { get; set; }
        public String OldAsignerUserName { get; set; }
        public String NewAsignerUserName { get; set; }
        public String EditorUserName { get; set; }
    }

    public class DefectClosedReOpenedEmailNotifyArg : EmailNotifyArg
    {

        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.DefectClosedReopened; }
        }

        public String DefectId { get; set; }
        public String EditorUserName { get; set; }

        #endregion
    }

    public class CommentOnDefectEmailNotifyArg : EmailNotifyArg
    {

        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.CommentOnDefect; }
        }

        public String CommentId { get; set; }

        #endregion
    }

    public class DisableEnableAccountEmailNotifyArg : EmailNotifyArg
    {

        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.DisableEnableAccount; }
        }

        public String UserName { get; set; }

        #endregion
    }

    public class ChangedProjectMembersEmailNotifyArg : EmailNotifyArg
    {

        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.ChangedProjectMembers; }
        }

        public String ProjectId { get; set; }
        public String UserName { get; set; }

        #endregion
    }

    public class PasswordResetedEmailNotifyArg : EmailNotifyArg
    {

        #region EmailNotifyArg Members

        public EmailNotificationType Type
        {
            get { return EmailNotificationType.ResetPassword; }
        }

        public String UserName { get; set; }
        public String NewPassword { get; set; }

        #endregion
    }
    #endregion 

    #region Email Notify Commands
    public interface ICommand
    {
        void Execute(EmailNotifyArg arg);
    }

    public class DefectStatusChangedNotifier : ICommand
    {
         DefectManagement DM = DefectManagement.GetInstance();
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            StatusChangedEmailNotifyArg Arg = (StatusChangedEmailNotifyArg) arg;

            Defect defect = DM.GetDefect(Arg.DefectId);
            Account Editor = AM.GetUserByUserName(Arg.EditorUserName);
            Account Creator = defect.AccountCreator;
            Account AssignTo = defect.AccountAssignedMember;

            if (defect != null && Editor!=null)
            {
                #region Create Defect Log
                DefectLog Log = new DefectLog();
                Log.LogId = Guid.NewGuid();
                Log.DefectId = defect.DefectId;
                Log.Content = String.Format("Status is changed from {0} to {1}", Arg.OldStatus, Arg.NewStatus);
                Log.User = Editor.AccountId;
                Log.CreatedTime = DateTime.Now;

                DM.AddDefectLog(Log);
                #endregion

                #region Send Email
                Object[] objs = { 
                                     Arg.EditorUserName, 
                                     String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId), 
                                     Arg.OldStatus, 
                                     Arg.NewStatus
                                 };

                String message = String.Format("{0} changed status of <a href='{1}'>defect</a> from {2} to {3}", objs);

                if (AM.GetEmailNotificationsSetings(Creator.UserName).Contains("DefectCreatedByMeStatusChange"))
                {
                    EmailSender.GetInstance().AddNewEmail(Creator.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                }

                if (AssignTo != null && AssignTo.UserName != Creator.UserName)
                {
                    if (AM.GetEmailNotificationsSetings(AssignTo.UserName).Contains("DefectAssignedToMeStatusChange"))
                    {
                        EmailSender.GetInstance().AddNewEmail(AssignTo.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                    }
                }
                #endregion
            }
        }

        #endregion
    }

    public class DefectCreatedNotifier : ICommand
    {
         DefectManagement DM = DefectManagement.GetInstance();
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            DefectCreatedNotifyArg Arg = (DefectCreatedNotifyArg)arg;

            Defect defect = DM.GetDefect(Arg.DefectId);
            Account Creator = defect.AccountCreator;

            if (defect != null)
            {
                #region Create Defect Log
                DefectLog Log = new DefectLog();
                Log.LogId = Guid.NewGuid();
                Log.DefectId = defect.DefectId;
                Log.Content = String.Format("This defect is created");
                Log.User = Creator.AccountId;
                Log.CreatedTime = DateTime.Now;

                DM.AddDefectLog(Log);
                #endregion

                #region Send Email

                String message = String.Format("This defect is created by {0}", Creator.UserName);

                if (AM.GetEmailNotificationsSetings(Creator.UserName).Contains("DefectCreatedByMe"))
                {
                    EmailSender.GetInstance().AddNewEmail(Creator.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                }

                #endregion
            }
        }

        #endregion
    }

    public class DefectAssignerChangedNotifier : ICommand
    {
         DefectManagement DM = DefectManagement.GetInstance();
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            AssignerChangedEmailNotifyArg AssignerChangedArg = (AssignerChangedEmailNotifyArg) arg;

            Defect defect = DM.GetDefect(AssignerChangedArg.DefectId);

            Account OldAssigner = AM.GetUserByUserName(AssignerChangedArg.OldAsignerUserName);
            Account NewAssigner = AM.GetUserByUserName(AssignerChangedArg.NewAsignerUserName);

            Account Editor = AM.GetUserByUserName(AssignerChangedArg.EditorUserName);

            if (defect != null && Editor != null && (OldAssigner != null || NewAssigner != null))
            {
                #region Create Defect Log
                DefectLog Log = new DefectLog();
                Log.LogId = Guid.NewGuid();
                Log.DefectId = defect.DefectId;

                if (OldAssigner == null)
                {
                    Object[] objs = {  
                                         AssignerChangedArg.NewAsignerUserName
                                     };

                    Log.Content = String.Format("Assigner is changed from nobody to {0}", objs);
                }
                else if (NewAssigner != null)
                {
                     Object[] objs = {  
                                         AssignerChangedArg.OldAsignerUserName,
                                         AssignerChangedArg.NewAsignerUserName
                                     };

                     Log.Content = String.Format("Assigner is changed from {0} to {1}", objs);
                }
                else
                {
                    Object[] objs = {  
                                         AssignerChangedArg.OldAsignerUserName
                                     };

                    Log.Content = String.Format("Assigner is changed from {0} to nobody", objs);
                }
                Log.User = Editor.AccountId;
                Log.CreatedTime = DateTime.Now;

                DM.AddDefectLog(Log);
                #endregion

                #region Send Email
                String message;

                if (OldAssigner == null)
                {
                    Object[] objs = {  
                                         AssignerChangedArg.EditorUserName,
                                         String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId), 
                                         AssignerChangedArg.NewAsignerUserName
                                     };

                    message = String.Format("{0} changed assigner of <a href='{1}'>defect</a> from nobody to {2}", objs);
                }
                else if (NewAssigner != null)
                {
                    Object[] objs = {  
                                         AssignerChangedArg.EditorUserName,
                                         String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId), 
                                         AssignerChangedArg.OldAsignerUserName,
                                         AssignerChangedArg.NewAsignerUserName
                                     };

                    message = String.Format("{0} changed assigner of <a href='{1}'>defect</a> from {2} to {3}", objs);
                }
                else
                {
                    Object[] objs = {  
                                         AssignerChangedArg.EditorUserName,
                                         String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId), 
                                         AssignerChangedArg.OldAsignerUserName,
                                     };

                    message = String.Format("{0} changed assigner of <a href='{1}'>defect</a> from {2} to nobody", objs);
                }

                if (OldAssigner != null)
                {
                    if (AM.GetEmailNotificationsSetings(OldAssigner.UserName).Contains("DefectReassignedToSomeOneElse"))
                    {
                        EmailSender.GetInstance().AddNewEmail(OldAssigner.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                    }
                }

                if (NewAssigner != null)
                {
                    if (AM.GetEmailNotificationsSetings(NewAssigner.UserName).Contains("DefectAssignedToMe"))
                    {
                        EmailSender.GetInstance().AddNewEmail(NewAssigner.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                    }
                }
                #endregion
            }        
        }

        #endregion
    }

    public class DefectClosedReopenedNotifier : ICommand
    {
         DefectManagement DM = DefectManagement.GetInstance();
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            DefectClosedReOpenedEmailNotifyArg Arg = (DefectClosedReOpenedEmailNotifyArg)arg;

            Defect defect = DM.GetDefect(Arg.DefectId);
            Account Editor = AM.GetUserByUserName(Arg.EditorUserName);
            Account Creator = defect.AccountCreator;
            Account AssignTo = defect.AccountAssignedMember;

            if (defect != null && Editor != null)
            {
                #region Create Defect Log
                DefectLog Log = new DefectLog();
                Log.LogId = Guid.NewGuid();
                Log.DefectId = defect.DefectId;
                if (defect.IsClosed)
                {
                    Log.Content = String.Format("This defect is closed");
                }
                else
                {
                    Log.Content = String.Format("This defect is reopened");
                }
                Log.User = Editor.AccountId;
                Log.CreatedTime = DateTime.Now;

                DM.AddDefectLog(Log);
                #endregion

                #region Send Email
                String message;
                if (defect.IsClosed)
                {
                    Object[] objs = { 
                                     String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId), 
                                     Arg.EditorUserName                                   
                                 };

                    message = String.Format("<a href='{0}'>Defect</a> is closed by {1}", objs);
                }
                else
                {
                    Object[] objs = { 
                                     String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId), 
                                     Arg.EditorUserName                                   
                                 };

                    message = String.Format("<a href='{0}'>Defect</a> is reopened by {1}", objs);
                }

                if (defect.IsClosed)
                {
                    if (AM.GetEmailNotificationsSetings(Creator.UserName).Contains("DefectCreatedByMeClosed"))
                    {
                        EmailSender.GetInstance().AddNewEmail(Creator.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                    }

                    if (AssignTo != null && AssignTo.UserName != Creator.UserName)
                    {
                        if (AM.GetEmailNotificationsSetings(AssignTo.UserName).Contains("DefectAssignedToMeClosed"))
                        {
                            EmailSender.GetInstance().AddNewEmail(AssignTo.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                        }
                    }
                }
                else
                {
                    if (AM.GetEmailNotificationsSetings(Creator.UserName).Contains("DefectCreatedByMeReOpened"))
                    {
                        EmailSender.GetInstance().AddNewEmail(Creator.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                    }

                    if (AssignTo != null && AssignTo.UserName != Creator.UserName)
                    {
                        if (AM.GetEmailNotificationsSetings(AssignTo.UserName).Contains("DefectAssignedToMeReOpened"))
                        {
                            EmailSender.GetInstance().AddNewEmail(AssignTo.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                        }
                    }
                }
                #endregion
            }
        }

        #endregion
    }

    public class CommentOnDefectNotifier : ICommand
    {
         DefectManagement DM = DefectManagement.GetInstance();
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            CommentOnDefectEmailNotifyArg Arg = (CommentOnDefectEmailNotifyArg) arg;

            Comment comment = DM.GetComment(Arg.CommentId);
            Defect defect = (Defect)comment.Defect;

            Account Creator = defect.AccountCreator;
            Account AssignTo = defect.AccountAssignedMember;

            if (comment != null)
            {
                #region Send Email
                Object[] objs = { 
                                    comment.Account.UserName,
                                    comment.Content,
                                    String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId)                                 
                                 };

                String message = String.Format("{0} comments \"{1}\" on <a href='{2}'>Defect</a>", objs);

                if (AM.GetEmailNotificationsSetings(Creator.UserName).Contains("DefectCreatedByMeNewComment"))
                {
                    EmailSender.GetInstance().AddNewEmail(Creator.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                }

                if (AssignTo != null && AssignTo.UserName != Creator.UserName)
                {
                    if (AM.GetEmailNotificationsSetings(AssignTo.UserName).Contains("DefectAssignedToMeNewComment"))
                    {
                        EmailSender.GetInstance().AddNewEmail(AssignTo.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                    }
                }
                #endregion
            }
        }

        #endregion
    }

    public class DefectPriorityChangedNotifier : ICommand
    {
         DefectManagement DM = DefectManagement.GetInstance();
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            PriorityChangedEmailNotifyArg Arg = (PriorityChangedEmailNotifyArg)arg;

            Defect defect = DM.GetDefect(Arg.DefectId);
            Account Editor = AM.GetUserByUserName(Arg.EditorUserName);
            Account Creator = defect.AccountCreator;
            Account AssignTo = defect.AccountAssignedMember;

            if (defect != null && Editor != null)
            {
                #region Create Defect Log
                DefectLog Log = new DefectLog();
                Log.LogId = Guid.NewGuid();
                Log.DefectId = defect.DefectId;
                Log.Content = String.Format("Ppriority is changed from {0} to {1}", Arg.OldPriority, Arg.NewPriority);
                Log.User = Editor.AccountId;
                Log.CreatedTime = DateTime.Now;

                DM.AddDefectLog(Log);
                #endregion

                #region Send Email
                Object[] objs = { 
                                     Arg.EditorUserName, 
                                     String.Format("{0}/Defect/Details/{1}", Utilities.ServerHostName(), defect.DefectId), 
                                     Arg.OldPriority, 
                                     Arg.NewPriority
                                 };

                String message = String.Format("{0} changed priority of <a href='{1}'>defect</a> from {2} to {3}", objs);

                if (AM.GetEmailNotificationsSetings(Creator.UserName).Contains("DefectCreatedByMePriorityChange"))
                {
                    EmailSender.GetInstance().AddNewEmail(Creator.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                }

                if (AssignTo != null && AssignTo.UserName != Creator.UserName)
                {
                    if (AM.GetEmailNotificationsSetings(AssignTo.UserName).Contains("DefectAssignedToMePriorityChange"))
                    {
                        EmailSender.GetInstance().AddNewEmail(AssignTo.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
                    }
                }
                #endregion
            }
        }

        #endregion
    }

    public class DisableEnableAccountNotifier : ICommand
    {
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            DisableEnableAccountEmailNotifyArg Arg = (DisableEnableAccountEmailNotifyArg)arg;

            Account Acc = AM.GetUserByUserName(Arg.UserName);

            if (Acc != null)
            {
                String message;

                if (!Acc.IsActive)
                {
                    message = "Your account is disable";
                }
                else
                {
                    message = "Your account is enable";
                }

                EmailSender.GetInstance().AddNewEmail(Acc.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
            }
        }

        #endregion
    }

    public class ChangedProjectMembersNotifier : ICommand
    {
         AccountManagement AM = AccountManagement.GetInstance();
        ProjectManagement PM = ProjectManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            ChangedProjectMembersEmailNotifyArg Arg = (ChangedProjectMembersEmailNotifyArg)arg;

            Account Acc = AM.GetUserByUserName(Arg.UserName);

            if (Acc != null)
            {
                ProjectMember Member = PM.GetProjectMember(Acc.AccountId.ToString(), Arg.ProjectId);

                String message;

                if (Member != null)
                {
                    Object[] objs = { 
                                        Arg.UserName, 
                                        String.Format("{0}/Project/ViewDetails/{1}", Utilities.ServerHostName(), Member.ProjectId.ToString())
                                    };

                    message = String.Format("{0} is added to <href ='{1}'>Project</a>", objs);
                }
                else
                {
                    Object[] objs = { 
                                        Arg.UserName, 
                                        Member.Project.ProjectName
                                    };

                    message = String.Format("{0} is removed from {1} Project", objs);
                }

                EmailSender.GetInstance().AddNewEmail(Acc.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
            }
        }

        #endregion
    }

    public class ResetPasswordNotifier : ICommand
    {
         AccountManagement AM = AccountManagement.GetInstance();

        #region ICommand Members

        public void Execute(EmailNotifyArg arg)
        {
            PasswordResetedEmailNotifyArg Arg = (PasswordResetedEmailNotifyArg)arg;

            Account Acc = AM.GetUserByUserName(Arg.UserName);

            if (Acc != null)
            {
                String message = String.Format("Your Account is reset password. Your New Password is {0}", Arg.NewPassword);

                EmailSender.GetInstance().AddNewEmail(Acc.Profiles.FirstOrDefault().Email, "Defect Tracking System", message);
            }
        }

        #endregion
    }
    #endregion

    public enum EmailNotificationType
    {
        DefectStatusChanged,
        DefectAssignerChanged,
        DefectClosedReopened,
        CommentOnDefect,
        DisableEnableAccount,
        ChangedProjectMembers,
        DefectCreated,
        DefectPriorityChanged,
        ResetPassword
    }
}